/**
 * www.easyplatform.cn ©2016
 */
package cn.easyplatform.studio.web.controller;

import cn.easyplatform.entities.BaseEntity;
import cn.easyplatform.entities.beans.list.ListBean;
import cn.easyplatform.entities.beans.page.PageBean;
import cn.easyplatform.entities.beans.table.TableBean;
import cn.easyplatform.entities.beans.table.TableField;
import cn.easyplatform.lang.Files;
import cn.easyplatform.lang.Streams;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.entity.GetEntityCmd;
import cn.easyplatform.studio.cmd.entity.PagingCmd;
import cn.easyplatform.studio.cmd.entity.QueryCmd;
import cn.easyplatform.studio.vos.EntityVo;
import cn.easyplatform.studio.vos.QueryResultVo;
import cn.easyplatform.studio.web.editors.Editor;
import cn.easyplatform.studio.web.editors.EntityEditor;
import cn.easyplatform.type.EntityType;
import org.apache.commons.lang3.RandomStringUtils;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Components;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zk.ui.util.Composer;
import org.zkoss.zul.*;
import org.zkoss.zul.event.PagingEvent;
import org.zkoss.zul.event.ZulEvents;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

/**
 * @author <a href="mailto:shiny_vc@163.com">陈云亮</a> <br/>
 * @since 2.0.0 <br/>
 */
public class EntityboxController implements Composer<Panel>,
        EventListener<Event> {

    private Editor editor;

    private Bandbox bandbox;

    private int code;

    private Grid grid;

    private Paging paging;

    private Panel comp;

    public void doAfterCompose(Panel comp) throws Exception {
        this.comp = comp;
        if (Executions.getCurrent().getArg().containsKey("editor"))
            editor = (Editor) Executions.getCurrent().getArg().get("editor");
        bandbox = (Bandbox) comp.getFirstChild().query("bandbox");
        String id = RandomStringUtils.randomAlphanumeric(10);
        comp.setId(id);
        code = (Integer) Executions.getCurrent().getArg().get("code");
        grid = new Grid();
        grid.setHflex("1");
        grid.setVflex("1");
        Columns cols = new Columns();
        cols.setSizable(true);
        cols.setParent(grid);
        Rows rows = new Rows();
        rows.setParent(grid);
        grid.setParent(bandbox.getParent());
        if (code < 10) {
            bandbox.detach();
            if (code == 1) {//系统变量列表
                comp.setTitle(Labels.getLabel("menu.variables"));
                Column col = new Column(
                        Labels.getLabel("entity.task.variables"));
                col.setHflex("2");
                col.setParent(cols);
                col = new Column(Labels.getLabel("entity.desp"));
                col.setHflex("3");
                col.setParent(cols);
                renderVariables();
            }
        } else {
            bandbox.addEventListener(Events.ON_OPEN, this);
            bandbox.addEventListener(Events.ON_OK, this);
            if (code == 52) {// 4
                String table = null;
                if (editor instanceof EntityEditor<?>) {
                    BaseEntity entity = ((EntityEditor<?>) editor).getEntity();
                    if (entity instanceof PageBean)
                        table = ((PageBean) entity).getTable();
                    else if (entity instanceof ListBean)
                        table = ((ListBean) entity).getTable();
                }
                if (Strings.isBlank(table)) {
                    comp.setTitle(Labels.getLabel("entity.table.title"));
                } else
                    comp.setTitle(table);
                Column col = new Column(
                        Labels.getLabel("entity.task.variables.name"));
                col.setHflex("2");
                col.setParent(cols);
                col = new Column(Labels.getLabel("entity.task.variables.desp"));
                col.setHflex("3");
                col.setParent(cols);
                if (!Strings.isBlank(table) && !table.startsWith("$"))
                    renderTable(table);
            } else if (code == 53) {// 5
                comp.setTitle(Labels.getLabel("editor.menu.tasks"));
                Column col = new Column(Labels.getLabel("entity.id"));
                col.setHflex("2");
                col.setParent(cols);
                col = new Column(Labels.getLabel("entity.name"));
                col.setHflex("3");
                col.setParent(cols);
                col = new Column(Labels.getLabel("entity.desp"));
                col.setHflex("4");
                col.setParent(cols);
                paging = new Paging();
                paging.setPageSize(20);
                paging.setParent(bandbox.getParent());
                paging.addEventListener(ZulEvents.ON_PAGING, this);
                queryTasks("");
            }
        }
        //Clients.evalJavaScript("epstudio.prepareEntityToolbox('" + id+ "')");
    }

    private void renderVariables() {
        Properties properties = new Properties();
        try {
            properties.load(Streams.utf8r(Files
                    .findFileAsStream("web/support/system.properties")));
            TreeMap<Object, Object> treeMap = new TreeMap<Object, Object>(properties);
            treeMap.remove("1000");
            for (Map.Entry<Object, Object> entry : treeMap.entrySet()) {
                Row row = new Row();
                row.appendChild(new Label((String) entry.getKey()));
                row.appendChild(new Label((String) entry.getValue()));
                row.setParent(grid.getRows());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void renderTable(String table) {
        TableBean e = (TableBean) StudioApp.execute(null, new GetEntityCmd(
                table));
        Components.removeAllChildren(grid.getRows());
        if (e != null && e.getFields() != null) {
            for (TableField tf : e.getFields()) {
                Row row = new Row();
                row.setValue(tf);
                row.setDraggable(EntityType.TABLE.getName());
                row.appendChild(new Label(tf.getName()));
                row.appendChild(new Label(tf.getDescription()));
                row.setParent(grid.getRows());
            }
        }
    }

    private void renderTableList(String val) {
        QueryResultVo result = StudioApp.execute(bandbox, new QueryCmd("Table", "*", val.trim(), 0));
        Components.removeAllChildren(grid.getRows());
        if (result != null && result.getEntities() != null) {
            for (EntityVo evo : result.getEntities()) {
                Row row = new Row();
                row.setValue(evo);
                row.setDraggable("TableList");
                row.appendChild(new Label(evo.getId()));
                row.appendChild(new Label(evo.getName()));
                row.setParent(grid.getRows());
                row.addEventListener(Events.ON_DOUBLE_CLICK, new EventListener<Event>() {
                    @Override
                    public void onEvent(Event event) throws Exception {
                        if (event.getTarget() instanceof Row) {
                            EntityVo vo = ((Row) event.getTarget()).getValue();
                            comp.setTitle(vo.getId());
                            comp.setCollapsible(true);
                            comp.setClosable(true);
                            renderTable(vo.getId());
                        }
                    }
                });
            }
        }
    }

    private void renderTask(List<EntityVo> data) {
        grid.getRows().getChildren().clear();
        //Components.removeAllChildren(grid.getRows());
        for (EntityVo vo : data) {
            Row row = new Row();
            row.setValue(vo);
            row.appendChild(new Label(vo.getId()));
            row.appendChild(new Label(vo.getName()));
            row.appendChild(new Label(vo.getDesp()));
            row.setDraggable(EntityType.TASK.getName());
            grid.getRows().appendChild(row);
        }
    }

    private void queryTasks(String val) {
        QueryResultVo result = StudioApp.execute(new QueryCmd(EntityType.TASK
                .getName(), "*", val, paging.getPageSize()));
        if (result != null) {
            paging.setTotalSize(result.getTotalSize());
            paging.setActivePage(0);
            renderTask(result.getEntities());
        }
    }

    @Override
    public void onEvent(Event event) throws Exception {
        if (event.getName().equals(ZulEvents.ON_PAGING)) {
            PagingEvent pe = (PagingEvent) event;
            int pageNo = pe.getActivePage() + 1;
            List<EntityVo> data = StudioApp.execute(paging, new PagingCmd(EntityType.TASK.getName(), "*",
                    bandbox.getValue(), paging.getPageSize(), pageNo));
            renderTask(data);
        } else {
            String val = null;
            if (event instanceof OpenEvent) {
                OpenEvent evt = (OpenEvent) event;
                val = (String) evt.getValue();
                bandbox.setValue(val);
            } else
                val = bandbox.getValue();
            if (code == 53) {
                queryTasks(val);
            } else if (code == 52 && !Strings.isBlank(val)) {
                //renderTable(val);
                renderTableList(val);
            }
        }
    }
}
